﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using BomberManServer.Gaming.Serialization;
using BomberManServer.Gaming.Serialization.Object.Player;
using BomberManServer.Gaming.Serialization.Object.Connection;

namespace BomberManServer.Gaming.Socket
{
    public class ActionListener : InGame
    {
        // the players
        List<PlayerSocket> players;
        // internal serializer
        Serializer serializer;

        // EVENTS

        public ActionListener(Game game) : base(game)
        {
            this.players = game.connections.connected;
            this.serializer = game.serializer;
        }

        // read all messages
        public void read()
        {
            foreach(PlayerSocket player in players) {
                read(player);
            }
        }

        private void read(PlayerSocket player)
        {
            while(player.client.Client.Available > 0) {
                // reset socket timeout
                player.activate();

                // create stream
                NetworkStream netStream = player.client.GetStream();

                // we will call functions depending on the first byte
                switch ( (Message) netStream.ReadByte())
                {
                    case Message.Move:
                        Move move;
                        serializer.DeSerialize(netStream, out move);
                        if(game.map.moveAvatar(player.player.avatar, move.direction ))
                            game.sender.onPlayerMove(player.player);
                        flush(player);
                        break;
                    case Message.PutBomb:
                        // no associated data
                        /*
                        if (game.map.plantBomb(player.player.avatar))
                        {
                            game.sender.onBombSet(player.player.avatar.bombs.Last());
                            game.sender.onPlayerMove(player.player);
                        }
                         * */
                        player.player.avatar.willPlantBomb();
                        flush(player);
                        // call associated function
                        break;
                    case Message.TriggerBomb:
                        // no associated data
                        // call associated function
                        // only when manual explosion, timer expire explosion is managed in bomb
                        player.player.avatar.triggerBomb();
                            //game.sender.onBombExplode(player.player.avatar.bombs.First());

                        
                        break;
                    case Message.SendKey:
                        // if you get here, you are screwed
                        // the client should have already send the key

                        break;
                    case Message.Ready:
                        // we need to notify someone that the player is ready
                        game.sender.onReady(player.player);
                        game.ruleKeeper.playerIsReady(player.player);
                        break;
                    default:
                        flush(player);
                        break;
                }
            }
        }

        private void flush(PlayerSocket player)
        {
            foreach (UInt16 x in Enumerable.Range(0, player.client.Client.Available))
                player.client.GetStream().ReadByte();
        }
    }
}
